/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.form.client.widget.item.impl;

import java.util.ArrayList;
import java.util.List;

import com.genia.toolbox.web.gwt.form.client.form.ComplexItem;
import com.genia.toolbox.web.gwt.form.client.manager.FormManager;
import com.genia.toolbox.web.gwt.form.client.manager.FormValidatorCommand;
import com.genia.toolbox.web.gwt.form.client.manager.RecordableFormManagerList;
import com.genia.toolbox.web.gwt.form.client.process.ProcessSortable;
import com.genia.toolbox.web.gwt.form.client.validator.ValidatorCallback;
import com.genia.toolbox.web.gwt.form.client.value.FormValues;
import com.genia.toolbox.web.gwt.form.client.widget.SortableWidget;
import com.genia.toolbox.web.gwt.form.client.widget.item.ComplexItemWidget;
import com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidgetModifyListener;
import com.google.gwt.user.client.DeferredCommand;

/**
 * the basic implementation of <code>SimpleItemWidget</code>. It is a
 * <code>Composite</code> that will be filled by its sub-classes.
 * 
 * @param <ITEM>
 *          the type of item handled by this widget.
 */
public abstract class AbstractComplexItemWidget<ITEM extends ComplexItem>
    extends AbstractItemWidget<ITEM>
    implements ComplexItemWidget, SortableWidget
{

  /**
   * the {@link List} of listeners for this widget.
   */
  private final transient ItemWidgetModifyListenerCollection itemWidgetModifyListenerCollection = new ItemWidgetModifyListenerCollection();



  /**
   * add a listener that is called each time the value of this object change.
   * 
   * @param modifyListener
   *          the callback
   * @see com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidget#addModifyListener(com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidgetModifyListener)
   */
  public void addModifyListener(ItemWidgetModifyListener modifyListener)
  {
    itemWidgetModifyListenerCollection.add(modifyListener);
  }

  /**
   * the {@link List} of
   * {@link com.genia.toolbox.web.gwt.form.client.manager.FormManager}
   * representing the current values of this item.
   */
  private final List<FormManager> formManagers;



  /**
   * move the given value to the given position.
   * 
   * @param oldIndex
   *          the index of the value to move
   * @param newIndex
   *          the index of the final destination of the value
   */
  public void moveValue(int oldIndex, int newIndex)
  {
    ProcessSortable.move(formManagers, oldIndex, newIndex);
    getItemWidgetModifyListenerCollection().onModify(this);
  }



  /**
   * constructor.
   * 
   * @param currentFormManager
   *          the {@link formManager} that handle the current form.
   * @param complexItem
   *          the complexItem this object represents
   */
  protected AbstractComplexItemWidget(final FormManager currentFormManager, final ITEM complexItem)
  {
    super(complexItem);
    formManagers = new RecordableFormManagerList(currentFormManager);
  }



  /**
   * validate that the values are acceptable.
   * 
   * @param callback
   *          the callback that is called once the validation is done
   */
  public void validate(final ValidatorCallback callback)
  {

    for (final FormManager formManager : getFormManagers()) {
      formManager.saveFormValues();
    }
    DeferredCommand.addCommand(new FormValidatorCommand(getFormManagers(), callback));
  }



  /**
   * getter for the formManagers property.
   * 
   * @return the formManagers
   */
  public List<FormManager> getFormManagers()
  {
    return formManagers;
  }



  /**
   * returns the current values of this item.
   * 
   * @return a {@link List} of
   *         {@link com.genia.toolbox.web.gwt.form.client.value.FormValues}
   *         representing the current values of this item
   */
  public List<FormValues> getValues()
  {
    List<FormValues> res = new ArrayList<FormValues>();
    for (final FormManager formManager : getFormManagers()) {
      formManager.saveFormValues();
      res.add(formManager.getFormValues());
    }
    return res;
  }



  /**
   * getter for the itemWidgetModifyListenerCollection property.
   * 
   * @return the itemWidgetModifyListenerCollection
   */
  protected ItemWidgetModifyListenerCollection getItemWidgetModifyListenerCollection()
  {
    return itemWidgetModifyListenerCollection;
  }

}
